<?php
namespace slinks\extensions\aop;

use slinks\core\DependencyInjection\Reference;

use slinks\core\DependencyInjection\Definition;

use slinks\core\DependencyInjection\ContainerBuilder;

use slinks\core\DependencyInjection\Extension\Extension;

/**
 * Provides AOP support for the Slinks Container. 
 * 
 * @author Navid Mitchell
 *
 */
class AopExtension extends Extension{
	
	public function autoproxyLoad($config, ContainerBuilder $container){
		
		if(isset($config["targets"]) && isset($config["interceptors"])){
			
			// make regex of all target patterns 
			$pattern = '';
			$i=0;
			foreach($config["targets"] as $target){
				if($i > 0){
					$pattern .= '|';
				}
				$pattern .= $target;
				$i++;
			}
			
			$pattern = '/'.$pattern.'/';
			
			// we keep a pattern for interceptors since we dont want to proxy them. it would create an infinite loop. 
			$interceptorPattern = '';
			
			// build interceptor reference 
			$interceptors = array();
			$i=0;
			foreach($config["interceptors"] as $interceptor){
				$interceptors[] = new Reference($interceptor);
				
				if($i > 0){
					$interceptorPattern .= '|';
				}
				$interceptorPattern .= $interceptor;
				$i++;
			}
			
			$interceptorPattern = '/'.$interceptorPattern.'/';
			
			// now proxy any matched services. 
			foreach($container->getDefinitions() as $id => $definition){
				if(preg_match($pattern, $id) && !preg_match($interceptorPattern, $id)){
					// if we have a match we change the current definition id and add a proxy in its place
					$targetId = $id . 'z_proxied_target';
					$container->setDefinition($targetId, $definition);
					
					// create proxy
					$proxyDef = new Definition('slinks\extensions\aop\core\AutoProxy',
											   array(new Reference($targetId),$interceptors));	
					
					$container->setDefinition($id, $proxyDef);						   
				}
			}
		}
		
	}
	
	/**
     * Returns the base path for the XSD files.
     *
     * @return string The XSD base path
     */
    public function getXsdValidationBasePath()
    {
         return __DIR__.'/schema';
    }

    /**
     * Returns the namespace to be used for this extension (XML namespace).
     *
     * @return string The XML namespace
     */
    public function getNamespace()
    {
        return 'http://www.mitchellsoftware.net/schema/dic/aop';
    }

    /**
     * Returns the recommended alias to use in XML.
     *
     * This alias is also the mandatory prefix to use when using YAML.
     *
     * @return string The alias
     */
    public function getAlias()
    {
        return 'aop';
    }
	
}
